package mqttclient;

/**
*
* Description:
* @author admin
* 2017年2月10日下午17:50:15
*/

import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttTopic;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

import callback.MqttclientCallback;





public final class ClientMQTT {

	private static final String TOPIC = "CJdata";
	private MqttClient client;
	private MqttConnectOptions options;
	private int RSconncetNum = 10;// MQtt重连时间
	private boolean IsConnect = false;// 当前mqtt连接状态
	private boolean IsRun = true;// 重连线程停止控制
	private String[] Ntopic1;// 保存订阅的主题
	private int[] NQos;// 保存订阅的质量
	private String NHOST;// mqtt端口
	private String Nclientid;// mqtt的ID

	public boolean isIsConnect() {
		return IsConnect;
	}

	public void setIsConnect(boolean isConnect) {
		IsConnect = isConnect;
	}

	public int getRSconncetNum() {
		return RSconncetNum;
	}

	public void setRSconncetNum(int rSconncetNum) {
		RSconncetNum = rSconncetNum;
	}

	public MqttClient getClient() {
		return client;
	}

	public void setClient(MqttClient client) {
		this.client = client;
	}

	public void destroyClient() {
		try {
			IsRun = false;
			this.client.disconnectForcibly();
			this.client.close();
			System.out.println("mqttclient end");
			// this.client.disconnect();
		} catch (MqttException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
	}

	/**
	 * 开启MQTT订阅
	 * 
	 * @param HOST
	 *            MQTTsever地址，如："tcp://localhost:1883";
	 * @param clientid
	 *            mqtt客户端唯一id
	 * @param userName
	 *            连接名字
	 * @param passWord
	 *            密码
	 * @param topic1
	 *            订阅的主题数组
	 * @param Qos
	 *            订阅的内容质量
	 */
	public void start(String HOST, String clientid, String userName, String passWord, String[] topic1, int[] Qos) {
		Ntopic1 = topic1;
		NQos = Qos;
		NHOST = HOST;
		Nclientid = clientid;
		// MQTT的连接设置
		options = new MqttConnectOptions();
		// 设置是否清空session,这里如果设置为false表示服务器会保留客户端的连接记录，这里设置为true表示每次连接到服务器都以新的身份连接
		options.setCleanSession(true);
		// 设置连接的用户名
		options.setUserName(userName);
		// 设置连接的密码
		options.setPassword(passWord.toCharArray());
		// 设置超时时间 单位为秒
		options.setConnectionTimeout(10);
		// 设置会话心跳时间 单位为秒 服务器会每隔1.5*20秒的时间向客户端发送个消息判断客户端是否在线，但这个方法并没有重连的机制
		options.setKeepAliveInterval(10);
		try {
			// host为主机名，clientid即连接MQTT的客户端ID，一般以唯一标识符表示，MemoryPersistence设置clientid的保存形式，默认为以内存保存
			client = new MqttClient(HOST, clientid, new MemoryPersistence());
			// 设置回调
			client.setCallback(new MqttclientCallback());
			MqttTopic topic = client.getTopic(TOPIC);
			// setWill方法，如果项目中需要知道客户端是否掉线可以调用该方法。设置最终端口的通知消息
			options.setWill(topic, "close".getBytes(), 2, true);
			client.connect(options);
			// 订阅消息
			client.subscribe(topic1, Qos);
			IsConnect = true;// 连接状态置true
			System.out.println("mqtt has connected");
			cq = 0;
		} catch (Exception e) {
			e.printStackTrace();
		}
		Thread T = new MyHreat();
		T.start();// 开启连载状态监听
	}

	// public static void main(String[] args) throws MqttException {
	// ClientMQTT client = new ClientMQTT();
	// client.start();
	// }
	/**
	 * mmqtt连接状态线程，若断开定时执行重连
	 * 
	 * @author KK
	 *
	 */
	private int cq = 0;

	private class MyHreat extends Thread {
		public void run() {
			byte clnum = 0;
			System.out.println("mqtt RSconncet thread has start..." + IsRun);
			while (IsRun) {
				if (IsConnect == false) {
					try {
						clnum++;
//						System.out.println("mqtt client  RSconncet," + clnum + "," + RSconncetNum+","+(clnum % 5));
						if (clnum >= RSconncetNum) {
							if (cq > 10) {
								RSconncetNum = RSconncetNum * cq;// 重连超过10次，每次重连间隔越来越长,每次延长10秒
							} else if (cq > 50) {
								//SystemTool.RestartSystem();// 重连超过50次，重启系统
							}
							if (clnum % 5 == 0) {
								cq++;
								clnum = 0;
								System.out.println("mqtt client RSconnceting....");
								//host为主机名，clientid即连接MQTT的客户端ID，一般以唯一标识符表示，MemoryPersistence设置clientid的保存形式，默认为以内存保存
								client = new MqttClient(NHOST, Nclientid, new MemoryPersistence());
								//设置回调
								client.setCallback(new MqttclientCallback());
								client.connect(options);
								client.subscribe(Ntopic1, NQos);
								IsConnect = true;// 连接状态置true
								System.out.println("mqtt client  RSconncet success");
								RSconncetNum = 10;
							}
						}
					} catch (Exception e) {
						// TODO: handle exception
					}
				}
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				} // 延时
					// TODO: handle exception
			}
		}
	}
}
